//
//  SEGWindmillComponent.m
//  RefreshDemo
//
//  Created by Clavis on 2019/1/2.
//  Copyright © 2019 Clavis. All rights reserved.
//

#import "SEGWindmillComponent.h"

#if __has_include(<Commom/YYBaseHeader.h>)
#import <Commom/YYBaseHeader.h>
#else
#import "YYBaseHeader.h"
#endif

@interface SEGWindmillComponent ()

@property (strong, nonatomic) UIPanGestureRecognizer *pan;

@end

@implementation SEGWindmillComponent

#pragma mark - 初始化
- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        // 准备工作
        [self prepare];
        
        // 默认是普通状态
        self.state = SEGRefreshStateIdle;
    }
    return self;
}

- (void)prepare {
    // 基本属性
    self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
    self.backgroundColor = [UIColor clearColor];
}

- (void)layoutSubviews {
    [self placeSubviews];
    
    [super layoutSubviews];
}

- (void)placeSubviews{}

- (void)willMoveToSuperview:(UIView *)newSuperview {
    [super willMoveToSuperview:newSuperview];
    
    // 如果不是UIScrollView，不做任何事情
    if (newSuperview && ![newSuperview isKindOfClass:[UIScrollView class]]) return;
    
    // 旧的父控件移除监听
    [self removeObservers];
    
    if (newSuperview) { // 新的父控件
        // 记录UIScrollView
        _scrollView = (UIScrollView *)newSuperview;
        
        // 设置宽度
        self.width = newSuperview.width;
        // 设置位置
        self.x = -_scrollView.seg_insetL;
        
        // 设置永远支持垂直弹簧效果
        _scrollView.alwaysBounceVertical = YES;
        // 记录UIScrollView最开始的contentInset
        _scrollViewOriginalInset = _scrollView.seg_inset;
        
        // 添加监听
        [self addObservers];
    }
}

- (void)drawRect:(CGRect)rect
{
    [super drawRect:rect];
    
    if (self.state == SEGRefreshStateWillRefresh) {
        // 预防view还没显示出来就调用了beginRefreshing
        self.state = SEGRefreshStateRefreshing;
    }
}


#pragma mark - KVO监听
- (void)addObservers
{
    NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;
    [self.scrollView addObserver:self forKeyPath:SEGRefreshKeyPathContentOffset options:options context:nil];
    [self.scrollView addObserver:self forKeyPath:SEGRefreshKeyPathContentSize options:options context:nil];
    self.pan = self.scrollView.panGestureRecognizer;
    [self.pan addObserver:self forKeyPath:SEGRefreshKeyPathPanState options:options context:nil];
}

- (void)removeObservers
{
    [self.superview removeObserver:self forKeyPath:SEGRefreshKeyPathContentOffset];
    [self.superview removeObserver:self forKeyPath:SEGRefreshKeyPathContentSize];
    [self.pan removeObserver:self forKeyPath:SEGRefreshKeyPathPanState];
    self.pan = nil;
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    // 遇到这些情况就直接返回
    if (!self.userInteractionEnabled) return;
    
    // 这个就算看不见也需要处理
    if ([keyPath isEqualToString:SEGRefreshKeyPathContentSize]) {
        [self scrollViewContentSizeDidChange:change];
    }
    
    // 看不见
    if (self.hidden) return;
    if ([keyPath isEqualToString:SEGRefreshKeyPathContentOffset]) {
        [self scrollViewContentOffsetDidChange:change];
    } else if ([keyPath isEqualToString:SEGRefreshKeyPathPanState]) {
        [self scrollViewPanStateDidChange:change];
    }
}

- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change{}
- (void)scrollViewContentSizeDidChange:(NSDictionary *)change{}
- (void)scrollViewPanStateDidChange:(NSDictionary *)change{}

#pragma mark - 公共方法
#pragma mark 设置回调对象和回调方法
- (void)setState:(SEGRefreshState)state
{
    _state = state;
    
    // 加入主队列的目的是等setState:方法调用完毕、设置完文字后再去布局子控件
    dispatch_async(dispatch_get_main_queue(), ^{
        [self setNeedsLayout];
    });
}

#pragma mark 进入刷新状态
- (void)beginRefreshing
{
    [UIView animateWithDuration:SEGRefreshFastAnimationDuration animations:^{
        self.alpha = 1.0;
    }];
    self.pullingPercent = 1.0;
    // 只要正在刷新，就完全显示
    if (self.window) {
        self.state = SEGRefreshStateRefreshing;
    } else {
        // 预防正在刷新中时，调用本方法使得header inset回置失败
        if (self.state != SEGRefreshStateRefreshing) {
            self.state = SEGRefreshStateWillRefresh;
            // 刷新(预防从另一个控制器回到这个控制器的情况，回来要重新刷新一下)
            [self setNeedsDisplay];
        }
    }
}

#pragma mark 结束刷新状态
- (void)endRefreshing
{
    dispatch_async(dispatch_get_main_queue(), ^{
        self.state = SEGRefreshStateIdle;
    });
}

#pragma mark 是否正在刷新
- (BOOL)isRefreshing
{
    return self.state == SEGRefreshStateRefreshing || self.state == SEGRefreshStateWillRefresh;
}

#pragma mark 自动切换透明度
- (void)setAutomaticallyChangeAlpha:(BOOL)automaticallyChangeAlpha {
    _automaticallyChangeAlpha = automaticallyChangeAlpha;
    
    if (self.isRefreshing) return;
    
    if (automaticallyChangeAlpha) {
        self.alpha = self.pullingPercent;
    } else {
        self.alpha = 1.0;
    }
}

#pragma mark 根据拖拽进度设置透明度
- (void)setPullingPercent:(CGFloat)pullingPercent
{
    _pullingPercent = pullingPercent;
    
    if (self.isRefreshing) return;
    
    if (self.isAutomaticallyChangeAlpha) {
        self.alpha = pullingPercent;
    }
}

#pragma mark - 内部方法
- (void)executeRefreshingCallback {
    dispatch_async(dispatch_get_main_queue(), ^{
        if (self.refreshingBlock) {
            self.refreshingBlock();
        }
        //        if ([self.refreshingTarget respondsToSelector:self.refreshingAction]) {
        //            SEGRefreshMsgSend(SEGRefreshMsgTarget(self.refreshingTarget), self.refreshingAction, self);
        //        }
        //        if (self.beginRefreshingCompletionBlock) {
        //            self.beginRefreshingCompletionBlock();
        //        }
    });
}
@end
